'######################################################################################
'Author  :         Sumit Gupta 
'Company :				 Vikasumit
'Date    :         12th August 2005
'Modify Date:      5th January 2007
'--------------------------------------------------------------------------------------
'Working / Note on File : 
'Class for Making a Sever For the Required Application
'It works With the clsClient In the Same DLL for Client Specific
'It only provide to connect and related thing
'5th Jan 2007
'Now you can set the limit of connection to be used bydefault it is 1 connection allowed
'######################################################################################

Imports System.IO
Imports System.Net
Imports System.Net.Sockets
Imports System.Threading

Public Class clsServer

#Region "Private Temparory Varibles for Properties"

  Private Const CON_CLASSVERSION As String = "1.0.20070105" 'Define the Class Version
  Private t_Port As Integer
  Private t_IPAddress As IPAddress

  Private myThread As Thread
  Private tcpServer As TcpListener
  Private mytcpclient As TcpClient

  Private recieveData As String

  Private t_MaxConnectionAllowed As Integer

#End Region

#Region "Public Events"

  Public Event ServerSetupMessage(ByVal msg As String, ByVal msgNo As Integer)
  Public Event ServerClosingError(ByVal msg As String, ByVal msgNo As Integer)
  Public Event ServerSetupError(ByVal msg As String, ByVal msgNo As Integer)
  Public Event DataRecieved(ByVal Data As String)
  Public Event ServerClosed()
  Public Event ClientAccepted()
#End Region

#Region "Public Property"

  'Get the Class Version
  Public ReadOnly Property ClassVersion() As String
    Get
      Return CON_CLASSVERSION
    End Get
  End Property

  Public Property IPAddr() As IPAddress
    Get
      Return t_IPAddress
    End Get
    Set(ByVal Value As IPAddress)
      t_IPAddress = Value
    End Set
  End Property

  Public Property Port() As Integer
    Get
      Return t_Port
    End Get
    Set(ByVal Value As Integer)
      t_Port = Value
    End Set
  End Property

  Public Property MaxConnectionAllowed() As Integer
    Get
      Return t_MaxConnectionAllowed
    End Get
    Set(ByVal Value As Integer)
      If Value > 1 Then
        t_MaxConnectionAllowed = Value
      End If
    End Set
  End Property

#End Region

#Region "Construtor"

  Public Sub clsServer()
    Me.MaxConnectionAllowed = 1
    Me.Port = 80
  End Sub

#End Region

#Region "Private Function"

  'function to valid basic objects of the class
  Private Function ValidateData() As Boolean
    If Me.Port < 1000 Then
      RaiseEvent ServerSetupError("Port No must be Greater than 1000", 10001)
      Return False
    End If
    'If IPAddress.IsLoopback(Me.IPAddr) Then
    '  RaiseEvent ServerSetupError("You have provided the loop Back Ip Address", 10002)
    '  Return False
    'End If
    Return True
  End Function


  'Fucntion for Listening the connection string
  Private Sub Listener()

    ' Buffer for reading data
    Dim bytes(1024) As [Byte]
    Dim data As [String] = Nothing
    Dim i As Int32

    Dim EstablishedConnection As Integer = 0
    While True
      '      RaiseEvent ServerSetupMessage("Waiting for Client", 11005)
      Try
        mytcpclient = tcpServer.AcceptTcpClient
        EstablishedConnection += 1
        If EstablishedConnection < MaxConnectionAllowed Then
          tcpServer.Stop() 'Stop from listening other connections
        End If
      Catch ex As Exception
        'Donot Capture it
      End Try

      RaiseEvent ClientAccepted()

      Dim nstream As NetworkStream = mytcpclient.GetStream

      ' Loop to receive all the data sent by the client.
      Try
        RaiseEvent ServerSetupMessage("Reciveing Data from Client", 11006)
        i = nstream.Read(bytes, 0, bytes.Length)
      Catch ex As Exception
        RaiseEvent ServerSetupError(ex.Message, 10004)
        Exit Sub
      End Try

      While (i <> 0)

        ' Translate data bytes to a ASCII string.
        data = System.Text.Encoding.ASCII.GetString(bytes, 0, i)
        recieveData = data
        RaiseEvent DataRecieved(data)

        'Process the data sent by the client.
        data = data.ToUpper()
        nstream.Flush()
        Try
          RaiseEvent ServerSetupMessage("Reciveing Data from Client", 11006)
          i = nstream.Read(bytes, 0, bytes.Length)
        Catch ex As Exception
          RaiseEvent ServerSetupError(ex.Message, 10004)
        End Try
      End While
    End While

  End Sub

#End Region

#Region "Public Function"

  'Main sub call this for startign server
  Public Function StartServer() As Boolean
    RaiseEvent ServerSetupMessage("Validating Data", 11001)
    If ValidateData() Then
      Dim Ip As IPAddress = IPAddress.Parse("0.0.0.0")  'Set to unknown Ip

      tcpServer = New TcpListener(Ip, Me.Port)  'Port to open
      RaiseEvent ServerSetupMessage("Collecting Data to Form Hosting", 11002)

      Try  'Try to open the Server 
        RaiseEvent ServerSetupMessage("Attempt to Start the Server", 11003)
        tcpServer.Start()   'Start the Server
        RaiseEvent ServerSetupMessage("Server Started successfully", 11004)
      Catch ex As SocketException
        RaiseEvent ServerSetupError(ex.Message, ex.ErrorCode)
        Return False
      Catch ex As Exception
        RaiseEvent ServerSetupError(ex.Message, 10003)
        Return False
      End Try
      'Set flags
      mytcpclient = New TcpClient
      RaiseEvent ServerSetupMessage("Waiting for Client", 11005)
      myThread = New Thread(AddressOf Listener)  'set up the Listener
      myThread.Start()  'Set the Thread for listening    
      Return True
    Else
      Return False
    End If
  End Function

  'Public Function to Make available the Values from the Network to Application
  Public Function GetInput() As String
    Return recieveData
  End Function

  'Public function to send the data to the network
  Public Function SendData(ByVal data As String) As Boolean
    Try
      Dim w As New System.IO.StreamWriter(mytcpclient.GetStream)
      w.Write(data)
      w.Flush()
    Catch ex As Exception

    End Try
  End Function

  Public Sub CloseConnection()
    Try
      mytcpclient.Close()
      tcpServer.Stop()
      myThread.Abort()
      RaiseEvent ServerClosed()
    Catch ex As Exception
      'Do nothing
      RaiseEvent ServerClosingError(ex.Message, 10004)
    End Try
  End Sub

#End Region

End Class